﻿using BlazorAdmin.Interface;
using BlazorAdmin.Logs;
using BlazorAdmin.Models;
using BlazorAdmin.Models.Dto;
using Longbow.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Pangeo.Admin.Tasks.Jobs;

namespace Pangeo.Admin.Tasks
{
    public class SystemTask
    {
        private readonly IJob jobService;
        private readonly IServiceScopeFactory scope;

        public SystemTask(IServiceScopeFactory _scopeFactory, IJob _jobService)
        {
            jobService = _jobService;
            scope = _scopeFactory;
        }

        public async Task<List<Job>> CheckSystemTask(List<Job> jobList, bool isRemove = false)
        {
            IScheduler? task;
            var isChanged = false;
            var taskList = TaskServicesManager.ToList();

            foreach (var item in jobList)
            {
                if (isRemove)
                    TaskServicesManager.Remove(item.JobCode);

                task = taskList.FirstOrDefault(t => t.Name == item.JobCode);
                if (task == null) // 不存在则，需要创建
                {
                    Action? job = null;
                    if (item.JobCode == SysConsts.SyncClientDeviceInfo) // 客户端上报设备信息
                    {
                        job = () => new SyncClientDeviceInfo(scope).Run();
                    }
                    else if (item.JobCode == SysConsts.UploadClientFile) // 上传客户端文件
                    {
                        job = () => new UploadClientFile(scope).Run();
                    }
                    else if (item.JobCode == SysConsts.PushWorkTimeToBI) // 推送班次数据到BI
                    {
                        job = () =>
                        {
                            Console.WriteLine("Task PushWorkTimeToBI Is Starting ...");
                            LogUtil.Info("Task PushWorkTimeToBI Is Starting ...");

                            var errMsg = new PushWorkTimeToBI(scope).Run().Result;

                            if (!string.IsNullOrEmpty(errMsg))
                            {
                                Console.WriteLine("Task PushWorkTimeToBI Run Error \n" + errMsg);
                                LogUtil.Info("Task PushWorkTimeToBI Run Error \n" + errMsg);
                                throw new Exception(errMsg); // 抛出异常，表示任务执行失败
                            }
                            else
                            {
                                Console.WriteLine("Task PushWorkTimeToBI Exec Success !");
                                LogUtil.Info("Task PushWorkTimeToBI Exec Success !");
                            }
                        };
                    }

                    if (job != null)
                    {
                        task = TaskServicesManager.GetOrAdd(item.JobCode, new WorkJob(job), TriggerBuilder.Build(item.CronExpress));
                    }
                }

                if (task == null)
                    continue;

                isChanged = false;
                if (task.LastRuntime.HasValue && item.LastExecTime != task.LastRuntime.Value.DateTime)
                {
                    item.LastExecTime = task.LastRuntime.Value.DateTime;
                    item.LastExecResult = task.LastRunResult.ToString();
                    isChanged = true;
                }

                if (task.NextRuntime.HasValue && item.NextExecTime != task.NextRuntime.Value.DateTime)
                {
                    item.NextExecTime = task.NextRuntime.Value.DateTime;
                    isChanged = true;
                }

                if (item.Status != task.Status.ToString())
                {
                    item.Status = task.Status.ToString();
                    isChanged = true;
                }

                if (isChanged)
                    await jobService.Save(item);
            }

            return jobList;
        }
    }
}
